﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using Game.Command.Internal;
using Game.Common.Resources;
using Game.Map;
using Game.Toolkit.Internal;
using Game.Types;
using Game.Controller;

namespace Game.Toolkit
{
    public static class StandardBuildings
    {
        static Dictionary<Point, Point> _Dictionary;
        
        public static GameObjectGroup Depot
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Depot");
                
                var image = BuildingResourceFile.Depot;
                
                GenImage(ref builder, image, new GameDirection(1, 1));
                GenImage(ref builder, image, new GameDirection(1, 0));
                GenImage(ref builder, image, new GameDirection(2, 1));
                
                return builder.Build();
            }
        }

        public static GameObjectGroup Depot2
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Depot2");

                var image = BuildingResourceFile.Depot2;

                GenImage(ref builder, image, new GameDirection(0, 1));
                GenImage(ref builder, image, new GameDirection(1, 1));
                GenImage(ref builder, image, new GameDirection(1, 0));
                return builder.Build();
            }
        }

        public static BuildingType HeadQuartersBuilding
        {
            get
            {
                var builder = new BuildingTypeBuilder {Name = "Headquaters"};
                builder.Tank.Energy.Value = 0;
                builder.Tank.Fuel.Value = 100;
                builder.Tank.Material.Value = 0;

                return builder.BuildBuildingType();
            }
        }
        
        public static GameObjectGroup HeadQuarters
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Head Quarters");

                var image = BuildingResourceFile.HeadQuarters;

                var typeBuilder = new BuildingTypeBuilder {Name = "Headquaters"};
                var building = typeBuilder.BuildBuildingType();
                builder.BuildingType = building;
                
                GenImage(ref builder, image, new GameDirection(1, 0));
                
                GenImage(ref builder, image, new GameDirection(0, 1));
                GenImage(ref builder, image, new GameDirection(1, 1));
                GenImage(ref builder, image, new GameDirection(2, 1));
                
                GenImage(ref builder, image, new GameDirection(0, 2));
                GenImage(ref builder, image, new GameDirection(1, 2));
                GenImage(ref builder, image, new GameDirection(2, 2));
                
                GenImage(ref builder, image, new GameDirection(1, 3));
                
                GenImage(ref builder, image, new GameDirection(1, 4));
                
                return builder.Build();
            }
        }
        
        public static GameObjectGroup Mine3
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Mine3");

                var image = BuildingResourceFile.Mine3;

                GenImage(ref builder, image, new GameDirection(1, 0));
                GenImage(ref builder, image, new GameDirection(0, 1));
                GenImage(ref builder, image, new GameDirection(1, 1));
                GenImage(ref builder, image, new GameDirection(2, 1));
                
                return builder.Build();
            }
        }
        
        public static GameObjectGroup Airport
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Airport");

                var image = BuildingResourceFile.Airport;

                GenImage(ref builder, image, new GameDirection(1, 0));
                GenImage(ref builder, image, new GameDirection(0, 1));
                GenImage(ref builder, image, new GameDirection(1, 1));
                GenImage(ref builder, image, new GameDirection(2, 1));
                
                return builder.Build();
            }
        }
        
//        public static GameObjectGroup NuclearPlant
//        {
//            get
//            {
//                GameObjectGroupBuilder builder =
//                    new GameObjectGroupBuilder("Nuclear Plant");
//                
//                ImageSource image = BuildingResourceFile.NuclearPlant;
//
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(0, 0));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(1, 0));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(2, 0));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(3, 0));
//                
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(0, 1));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(1, 1));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(2, 1));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(3, 1));
//                
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(0, 2));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(1, 2));
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(2, 2));
//                
//                GenImage(ref builder, image.ToWinFormsBitmap(), new GameDirection(1, 3));
//                
//                return builder.Build();
//            }
//        }
        
        public static GameObjectGroup Windpower
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Windpower");

                var image = BuildingResourceFile.Windpower;

                GenImage(ref builder, image, new GameDirection(0, 0));
                GenImage(ref builder, image, new GameDirection(1, 0));
                GenImage(ref builder, image, new GameDirection(2, 0));
                
                return builder.Build();
            }
        }
        
        public static GameObjectGroup Factory
        {
            get
            {
                var ability = new BuildUnitAbility();
                var queueX = new CommandQueueExtensionFactory();

                var tank = new GameResources(0, 0, 20);
                var builder = new GameObjectGroupBuilder(
                    "Factory", ability, queueX, tank);

                var image = BuildingResourceFile.Factory;

                GenImage(ref builder, image, new GameDirection(1, 0));
                GenImage(ref builder, image, new GameDirection(2, 0));
                
                GenImage(ref builder, image, new GameDirection(1, 1));
                GenImage(ref builder, image, new GameDirection(2, 1));
                
                return builder.Build();
            }
        }
        
        public static GameObjectGroup Solar
        {
            get
            {
                var builder = new GameObjectGroupBuilder("Solar");
                
                var image = BuildingResourceFile.Solar;

                GenImage(ref builder, image, new GameDirection(1, 0));
                GenImage(ref builder, image, new GameDirection(2, 0));
                GenImage(ref builder, image, new GameDirection(3, 0));
                
                GenImage(ref builder, image, new GameDirection(2, 1));
                
                return builder.Build();
            }
        }
        
        const double INFLATE = 2.6;
        
        static void GenImage(
            ref GameObjectGroupBuilder builder,
            BitmapImage  image,
            GameDirection dir)
        {
            var point = new Point(dir.Value.X,dir.Value.Y);
            if (!GetTranslateDictionary().ContainsKey(point))
            {
                Debugger.Break();
            }
            
            var newPoint = GetTranslateDictionary()[point];

            var group = new TransformGroup();
            var translate = new TranslateTransform();
            var scale = new ScaleTransform();
            group.Children.Add(translate);
            group.Children.Add(scale);
            
            translate.X = -newPoint.X;
            translate.Y = -newPoint.Y;
            
            translate.X += 0;
            translate.Y += 0;
            
            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext context = drawingVisual.RenderOpen();
            
            scale.ScaleX = image.Width / (32 * INFLATE);
            scale.ScaleY = image.Height / (48 * INFLATE);
            context.DrawImage(image, new Rect(0, 0, image.Width, image.Height));
            context.Close();
            
            RenderTargetBitmap target = new RenderTargetBitmap(
                (int)image.Width, (int)image.Height, 
                96, 96, PixelFormats.Pbgra32);
            drawingVisual.Transform = group;
            target.Render(drawingVisual);
            
            EditableImage ei = EditableImage.Create(target);
            
            var mm = new BitmapImage();
            mm.BeginInit();
            mm.StreamSource = ei.GetStream();
            mm.EndInit();
            
            builder.Add(dir, mm);
        }
        
        public static Dictionary<Point, Point> GetTranslateDictionary()
        {
            if (_Dictionary != null)
            {
                return _Dictionary;
            }
            
            _Dictionary = new Dictionary<Point, Point>();
            
            for(int x = 0; x < 10; x++)
            {
                for(int y = 0; y < 10; y++)
                {
                    int newX = x * (int)(32 * (INFLATE/2));
                    int newY = y * (int)(48 * (INFLATE/2));
                    if ((x % 2) == 1)
                    {
                        newY += (int)(24 * (INFLATE/2));
                    }
                    
                    var p1 = new Point(x, y);
                    var p2 = new Point(newX, newY);
                    _Dictionary.Add(p1, p2);
                }
            }
            
            return _Dictionary;
        }
        
    }
}
